/**
 * field_tree
 */
layui.define(['YunjField','yunj','jquery'], function (exports) {

    let YunjField = layui.YunjField;
    let win = window;
    let doc = document;
    let $ = layui.jquery;

    class YunjTree extends YunjField {

        constructor(options={}) {
            super(options);
            this.mode = null;                  // 模式
            this.all_optional = null;          // 是否所有可选
            this.retract_level = null;         // 是否所有可选
            this.nodes = null;
            this.node_idx_map = null;           // 节点id与对应下标的映射关系
            this.show_box_el=null;
            this.txt_box_el=null;
            this.icon_el=null;
            this.filter_box_el=null;
            this.filter_tree_el=null;
            this.ztree=null;
        }

        defineExtraArgs(){
            let that = this;
            return {
                value:"",
                mode:"checkbox",
                nodes:[],
                all_optional:false,
                retract_level:-1,
                disabled:false
            };
        }

        defineBoxHtml(){
            let that = this;
            return `<div class="layui-form-item yunj-form-item yunj-form-tree" id="${that.id}">__layout__</div>`;
        }

        layoutControl() {
            let that = this;
            let controlHtml = `<div class="show-box">
                                    <div class="txt-box" data-ids=""></div>
                                    <i class="layui-icon layui-icon-triangle-d"></i>
                                </div><div class="filter-box"><ul class="filter-tree ztree"></ul></div>`;
            return `<div class="layui-input-inline yunj-input-inline">${controlHtml}</div>`;
        }

        async renderBefore(){
            let that=this;
            that.mode = that.args.mode;
            that.all_optional = that.args.all_optional;
            that.retract_level = that.args.retract_level;
            that.set_nodes();
            win.jQuery=$;
            await yunj.include_css('/static/yunj/libs/zTree_v3/css/demo.css');
            await yunj.include_css('/static/yunj/libs/zTree_v3/css/metroStyle/metroStyle.css');
            await yunj.include_js('/static/yunj/libs/zTree_v3/js/jquery.ztree.core.js');
            await yunj.include_js('/static/yunj/libs/zTree_v3/js/jquery.ztree.excheck.js');
            await yunj.include_js('/static/yunj/libs/zTree_v3/js/jquery.ztree.exedit.js');
            return 'done';
        }

        set_nodes(){
            let that=this;
            let nodes=that.args.nodes;
            let nodeMap=new Map();
            let l=nodes.length;
            for(let i=0;i<l;i++){
                // id string
                nodes[i].id=nodes[i].id.toString();
                let node=nodes[i];
                let id=node.id;
                nodeMap.set(id,i);
                // 展开收起
                let open=true;
                if(that.retract_level>=0) open=node.level<that.retract_level;
                nodes[i].open=open;
                // 是否可选
                if(that.all_optional) continue;
                let nocheck=false;
                for(let j=0;j<l;j++){
                    if(id!==nodes[j].pid.toString()) continue;
                    nocheck=true;
                    break;
                }
                nodes[i].nocheck=nocheck;
            }
            that.nodes=nodes;
            that.node_idx_map=nodeMap;
        }

        renderDone() {
            let that=this;
            that.show_box_el=that.fieldBoxEl.find('.show-box');
            that.txt_box_el=that.fieldBoxEl.find('.show-box .txt-box');
            that.icon_el=that.fieldBoxEl.find('.layui-icon-triangle-d');
            that.filter_box_el=that.fieldBoxEl.find('.filter-box');
            that.filter_tree_el=that.fieldBoxEl.find('.filter-box .filter-tree');
        }

        setValue(val='',isReset){
            let that=this;
            let ids=yunj.isArray(val)?val:(val.length<=0?[]:(yunj.isJson(val)?JSON.parse(val):[val]));
            val=[];
            let valTxt="";
            for(let i=0,l=ids.length;i<l;i++){
                let id=ids[i].toString();
                if(!that.node_idx_map.has(id)) continue;
                let idx=that.node_idx_map.get(id);
                val.push(id);
                valTxt+=`、${that.nodes[idx].name}`;
            }
            if(valTxt.length>0) valTxt=valTxt.substr(1);
            that.txt_box_el.data("ids",JSON.stringify(val));
            that.txt_box_el.html(valTxt);
            if(isReset) that.render_filter_tree();
        }

        getValue(){
            let that=this;
            let ids=that.txt_box_el.data("ids");
            ids = JSON.parse(ids);
            return that.mode!=='radio'?ids:(ids.length>0?ids[0]:'');
        }

        // 展开筛选
        open_filter_box(){
            let that=this;
            that.icon_el.removeClass('icon-down').addClass('icon-up').css({"transform":`rotate(180deg)`});
            let top=that.show_box_el.offset().top + that.show_box_el.outerHeight() - $(win).scrollTop();
            // 上下定位
            if(top + 300 > $(win).height() && top >= 300){
                that.filter_box_el.css({'top':'','bottom':'42px'});
            }else {
                that.filter_box_el.css({'top':'42px','bottom':''});
            }
            if(that.filter_tree_el.html().length<=0) that.render_filter_tree();
            that.filter_box_el.show();
        }

        render_filter_tree(){
            let that=this;
            let ids=that.txt_box_el.data("ids");
            ids=ids.length>=0?JSON.parse(ids):[];
            let nodes=that.nodes;
            for(let i=0,l=ids.length;i<l;i++){
                let id=ids[i];
                if(!that.node_idx_map.has(id)) continue;
                let idx=that.node_idx_map.get(id);
                nodes[idx].checked=true;
            }
            let setting = {
                view: {
                    showIcon:false,
                },
                check: {
                    enable: true,
                },
                data: {
                    simpleData: {
                        enable: true,
                        pIdKey:"pid",
                    }
                },
                callback: {
                    onClick: function (e, treeId, tree_node, clickFlag) {
                        that.ztree.checkNode(tree_node, !tree_node.checked, true);
                        let nodes=that.ztree.getCheckedNodes(true);
                        let val=[];
                        for(let i=0;i<nodes.length;i++){
                            val.push(nodes[i].id);
                        }
                        that.setValue(val);
                    },
                    onCheck: function (e, treeId, tree_node) {
                        let nodes=that.ztree.getCheckedNodes(true);
                        let val=[];
                        for(let i=0;i<nodes.length;i++){
                            val.push(nodes[i].id);
                        }
                        that.setValue(val);
                    }
                }
            };
            switch (that.mode){
                case "radio":
                    setting.check.chkStyle="radio";
                    setting.check.radioType="all";
                    break;
            }
            that.ztree=$.fn.zTree.init(that.filter_tree_el, setting, that.nodes);
        }

        // 关闭筛选
        close_filter_box(){
            let that=this;
            that.icon_el.removeClass('icon-up').addClass('icon-down').css({"transform":`rotate(0deg)`});
            that.filter_box_el.hide();
        }

        defineExtraEventBind(){
            let that=this;

            $(doc).on('click',function (e) {
                if(!that.filter_box_el.is(e.target)&&that.filter_box_el.has(e.target).length === 0&&
                    !that.show_box_el.is(e.target)&&that.show_box_el.has(e.target).length === 0)
                    that.close_filter_box();
            });

            that.fieldBoxEl.on('click','.txt-box',function (e) {
                if(that.args.disabled) return false;
                let isOpen=that.icon_el.hasClass('icon-down')||(!that.icon_el.hasClass('icon-down')&&!that.icon_el.hasClass('icon-up'));
                if(isOpen){
                    that.open_filter_box();
                }else {
                    that.close_filter_box();
                }
                e.stopPropagation();
            });

        }

    }

    exports('field_tree', YunjTree);
});